using System;
using System.Collections.Generic;
using Nop.Core.Domain.Discounts;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Security;
using Nop.Core.Domain.Seo;
using Nop.Core.Domain.Catalog;
using Nop.Core.ApiDataModel.Catalog;
using System.Linq;

namespace Nop.Core.ApiDataModel
{
	/// <summary>
	/// Represents a Product MVC API DataModel.
	/// </summary>
    public partial class OrderModel
    {
        public ICollection<OrderProductModel> OrderProduct {get; set;}

		public int OrderId { get; set; }
        /// <summary>
        /// Gets or sets the store identifier which the order belongs
        /// </summary>
        public int? StoreId { get; set; }

        /// <summary>
        /// Gets or sets the district identifier
        /// </summary>
        public int DistrictId { get; set; }

        /// <summary>
        /// Gets or sets the billing address identifier
        /// </summary>
        public int BillingAddressId { get; set; }

        /// <summary>
        /// Gets or sets the shipping address identifier
        /// </summary>
        public int? ShippingAddressId { get; set; }

        /// <summary>
        /// Gets or sets an order status
        /// </summary>
        public string OrderStatus { get; set; }

        /// <summary>
        /// Gets or sets the shipping status
        /// </summary>
        public string ShippingStatus { get; set; }

        /// <summary>
        /// Gets or sets the payment status
        /// </summary>
        public string PaymentStatus { get; set; }

        /// <summary>
        /// Gets or sets the payment method system name
        /// </summary>
        public string PaymentMethodSystemName { get; set; }

        /// <summary>
        /// Gets or sets the customer currency code (at the moment of order placing)
        /// </summary>
        public string CustomerCurrencyCode { get; set; }

        /// <summary>
        /// Gets or sets the currency rate
        /// </summary>
        public decimal CurrencyRate { get; set; }

        /// <summary>
        /// Gets or sets the customer tax display type identifier
        /// </summary>
        public int CustomerTaxDisplayTypeId { get; set; }

        /// <summary>
        /// Gets or sets the VAT number (the European Union Value Added Tax)
        /// </summary>
        public string VatNumber { get; set; }

        /// <summary>
        /// Gets or sets the order subtotal (incl tax)
        /// </summary>
        public decimal OrderSubtotalInclTax { get; set; }

        /// <summary>
        /// Gets or sets the order subtotal (excl tax)
        /// </summary>
        public decimal OrderSubtotalExclTax { get; set; }

        /// <summary>
        /// Gets or sets the order subtotal discount (incl tax)
        /// </summary>
        public decimal OrderSubTotalDiscountInclTax { get; set; }

        /// <summary>
        /// Gets or sets the order subtotal discount (excl tax)
        /// </summary>
        public decimal OrderSubTotalDiscountExclTax { get; set; }

        /// <summary>
        /// Gets or sets the order shipping (incl tax)
        /// </summary>
        public decimal OrderShippingInclTax { get; set; }

        /// <summary>
        /// Gets or sets the order shipping (excl tax)
        /// </summary>
        public decimal OrderShippingExclTax { get; set; }

        /// <summary>
        /// Gets or sets the payment method additional fee (incl tax)
        /// </summary>
        public decimal PaymentMethodAdditionalFeeInclTax { get; set; }

        /// <summary>
        /// Gets or sets the payment method additional fee (excl tax)
        /// </summary>
        public decimal PaymentMethodAdditionalFeeExclTax { get; set; }

        /// <summary>
        /// Gets or sets the tax rates
        /// </summary>
        public string TaxRates { get; set; }

        /// <summary>
        /// Gets or sets the order tax
        /// </summary>
        public decimal OrderTax { get; set; }

	    /// <summary>
        /// Gets or sets the order discount (applied to order total)
        /// </summary>
        public decimal OrderDiscount { get; set; }

        /// <summary>
        /// Gets or sets the order total
        /// </summary>
        public decimal OrderTotal { get; set; }

        /// <summary>
        /// Gets or sets the refunded amount
        /// </summary>
        public decimal RefundedAmount { get; set; }

        /// <summary>
        /// Gets or sets the value indicating whether reward points were earned for this order
        /// </summary>
        public bool RewardPointsWereAdded { get; set; }

        /// <summary>
        /// Gets or sets the checkout attribute description
        /// </summary>
        public string CheckoutAttributeDescription { get; set; }

        /// <summary>
        /// Gets or sets the checkout attributes in XML format
        /// </summary>
        public string CheckoutAttributesXml { get; set; }

        /// <summary>
        /// Gets or sets the customer language identifier
        /// </summary>
        public int CustomerLanguageId { get; set; }

        /// <summary>
        /// Gets or sets the affiliate identifier
        /// </summary>
        public int? AffiliateId { get; set; }

        /// <summary>
        /// Gets or sets the customer IP address
        /// </summary>
        public string CustomerIp { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether storing of credit card number is allowed
        /// </summary>
        public bool AllowStoringCreditCardNumber { get; set; }

        /// <summary>
        /// Gets or sets the card type
        /// </summary>
        public string CardType { get; set; }

        /// <summary>
        /// Gets or sets the card name
        /// </summary>
        public string CardName { get; set; }

        /// <summary>
        /// Gets or sets the card number
        /// </summary>
        public string CardNumber { get; set; }

        /// <summary>
        /// Gets or sets the masked credit card number
        /// </summary>
        public string MaskedCreditCardNumber { get; set; }

        /// <summary>
        /// get tax
        /// </summary>
        public List<TaxSurchargeModel> TaxSurcharges { get; set; }
        /// <summary>
        /// Gets or sets the purchase order number
        /// </summary>
        public string PurchaseOrderNumber { get; set; }

        /// <summary>
        /// Gets or sets the paid date and time
        /// </summary>
        public DateTime? PaidDateUtc { get; set; }

        /// <summary>
        /// Gets or sets the shipping method
        /// </summary>
        public string ShippingMethod { get; set; }

        /// <summary>
        /// Gets or sets the shipping rate computation method identifier
        /// </summary>
        public string ShippingRateComputationMethodSystemName { get; set; }

        /// <summary>
        /// Gets or sets the date and time of order creation
        /// </summary>
        public DateTime CreatedOnUtc { get; set; }

        /// <summary>
        /// Gets or sets the related invoice identifier
        /// </summary>
        public int? InvoiceId { get; set; }

        /// <summary>
        /// Gets or sets whether this is a pure logistics order
        /// </summary>
        public int? OrderKindId { get; set; }

        /// <summary>
        /// Gets or sets the bound order identifier if this is a logistics order.
        /// </summary>
        public int? BoundOrderId { get; set; }

        /// <summary>
        /// Gets or sets the customized order by information
        /// </summary>
        public string OrderByInfo { get; set; }

        public OrderModel()
        {

        }

        public OrderModel(Nop.Core.Domain.Orders.Order order)
        {
			this.OrderId = order.Id;
            this.AffiliateId = order.AffiliateId;
            this.AllowStoringCreditCardNumber = order.AllowStoringCreditCardNumber;
            this.BillingAddressId = order.BillingAddressId;
            this.BoundOrderId = order.BoundOrderId;
            this.CardName = order.CardName;
            this.CardNumber = order.CardNumber;
            this.CardType = order.CardType;
            this.CheckoutAttributeDescription = order.CheckoutAttributeDescription;
            this.CheckoutAttributesXml = order.CheckoutAttributesXml;
            this.CreatedOnUtc = order.CreatedOnUtc;
            this.CurrencyRate = order.CurrencyRate;
            this.CustomerCurrencyCode = order.CustomerCurrencyCode;
            this.CustomerIp = order.CustomerIp;
            this.CustomerLanguageId = order.CustomerLanguageId;
            this.CustomerTaxDisplayTypeId = order.CustomerTaxDisplayTypeId;
            this.DistrictId = order.DistrictId;
            this.InvoiceId = order.InvoiceId;
            this.MaskedCreditCardNumber = order.MaskedCreditCardNumber;
            this.OrderByInfo = order.OrderByInfo;
            this.OrderDiscount = order.OrderDiscount;
            this.OrderKindId = order.OrderKindId;
            this.OrderProduct = new List<OrderProductModel>();
            order.OrderProductVariants.ToList().ForEach(
                orderPV => this.OrderProduct.Add(new OrderProductModel(orderPV))
            );
            this.OrderShippingExclTax = order.OrderShippingExclTax;
            this.OrderShippingInclTax = order.OrderShippingInclTax;
            this.OrderStatus = order.OrderStatus.ToString();
            this.OrderSubTotalDiscountExclTax = order.OrderSubTotalDiscountExclTax;
            this.OrderSubTotalDiscountInclTax = order.OrderSubTotalDiscountInclTax;
            this.OrderSubtotalExclTax = order.OrderSubtotalExclTax;
            this.OrderSubtotalInclTax = order.OrderSubtotalInclTax;
            this.OrderTax = order.OrderTax;
            this.OrderTotal = order.OrderTotal;
            this.PaidDateUtc = order.PaidDateUtc;
            this.PaymentMethodAdditionalFeeExclTax = order.PaymentMethodAdditionalFeeExclTax;
            this.PaymentMethodAdditionalFeeInclTax = order.PaymentMethodAdditionalFeeInclTax;
            this.PaymentMethodSystemName = order.PaymentMethodSystemName;
            this.PaymentStatus = order.PaymentStatus.ToString();
            this.PurchaseOrderNumber = order.PurchaseOrderNumber;
            this.RefundedAmount = order.RefundedAmount;
            this.RewardPointsWereAdded = order.RewardPointsWereAdded;
            this.ShippingAddressId = order.ShippingAddressId;
            this.ShippingMethod = order.ShippingMethod;
            this.ShippingRateComputationMethodSystemName = order.ShippingRateComputationMethodSystemName;
            this.ShippingStatus = order.ShippingStatus.ToString();
            this.StoreId = order.StoreId;
            this.TaxRates = order.TaxRates;
            this.VatNumber = order.VatNumber;
        }
    }

        public partial class OrderProductModel
        {
            /// <summary>
            /// Gets or sets the product variant identifier
            /// </summary>
            public virtual int ProductId { get; set; }

            /// <summary>
            /// Gets or sets the quantity
            /// </summary>
            public virtual int Quantity { get; set; }

            /// <summary>
            /// Gets or sets the unit price in primary store currency (incl tax)
            /// </summary>
            public virtual decimal UnitPriceInclTax { get; set; }

            /// <summary>
            /// Gets or sets the unit price in primary store currency (excl tax)
            /// </summary>
            public virtual decimal UnitPriceExclTax { get; set; }

            /// <summary>
            /// Gets or sets the price in primary store currency (incl tax)
            /// </summary>
            public virtual decimal PriceInclTax { get; set; }

            /// <summary>
            /// Gets or sets the price in primary store currency (excl tax)
            /// </summary>
            public virtual decimal PriceExclTax { get; set; }

            /// <summary>
            /// Gets or sets the discount amount (incl tax)
            /// </summary>
            public virtual decimal DiscountAmountInclTax { get; set; }

            /// <summary>
            /// Gets or sets the discount amount (excl tax)
            /// </summary>
            public virtual decimal DiscountAmountExclTax { get; set; }

            /// <summary>
            /// Gets or sets the attribute description
            /// </summary>
            public virtual string AttributeDescription { get; set; }

            /// <summary>
            /// Gets or sets the product variant attributes in XML format
            /// </summary>
            public virtual string AttributesXml { get; set; }

            /// <summary>
            /// Gets or sets the download count
            /// </summary>
            public virtual int DownloadCount { get; set; }

            /// <summary>
            /// Gets or sets a value indicating whether download is activated
            /// </summary>
            public virtual bool IsDownloadActivated { get; set; }

            /// <summary>
            /// Gets or sets a value indicating whether the product variant is partially refund
            /// </summary>
            public virtual bool? IsRefund { get; set; }

            /// <summary>
            /// Gets or sets quantity of opv when the product variant is partially refund
            /// </summary>
            public virtual int? RefundQuantity { get; set; }

            /// <summary>
            /// Gets or sets a license download identifier (in case this is a downloadable product)
            /// </summary>
            public virtual int? LicenseDownloadId { get; set; }

            /// <summary>
            /// Gets or sets the total weight of one item
            /// It's nullable for compatibility with the previous version of nopCommerce where was no such property
            /// </summary>
            public virtual decimal? ItemWeight { get; set; }

			public virtual List<KeyValuePair<string, string>> Attributes { get; set; }

            public OrderProductModel()
            {

            }

            public OrderProductModel(Nop.Core.Domain.Orders.OrderProductVariant orderPV)
            {
                this.AttributeDescription = orderPV.AttributeDescription;
                this.AttributesXml = orderPV.AttributesXml;
                this.DiscountAmountExclTax = orderPV.DiscountAmountExclTax;
                this.DiscountAmountInclTax = orderPV.DiscountAmountInclTax;
                this.DownloadCount = orderPV.DownloadCount;
                this.IsDownloadActivated = orderPV.IsDownloadActivated;
                this.IsRefund = orderPV.IsRefund==1;
                this.ItemWeight = orderPV.ItemWeight;
                this.LicenseDownloadId = orderPV.LicenseDownloadId;
                this.PriceExclTax = orderPV.PriceExclTax;
                this.PriceInclTax = orderPV.PriceInclTax;
                this.ProductId = orderPV.ProductVariantId;
                this.Quantity = orderPV.Quantity;
                this.RefundQuantity = orderPV.RefundQuantity;
                this.UnitPriceExclTax = orderPV.UnitPriceExclTax;
                this.UnitPriceInclTax = orderPV.UnitPriceInclTax;
            }
        }

}
